/*
 * Date         Author        Note
 * 2015.04.27   wzwz          增加度目前置量
 * 2015.06.25   wzwz          矫正右边续片纱嘴号
 * 2015.06.25   wzwz          修改卸片起点bug
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <mh/common.h>
#include <mh/com.h>
#include <mh/sram.h>
#include "knit.h"
#include "prefixknit.h"
#include "backpiece.h"
#include "compress.h"

#define MAC_NORMAL                        0
#define MAC_SINK_FOR_CAM                  1
#define MAC_EIGHT_GROUP_XZQ               2
#define MAC_DOUBLE_JITOU                  3
#define MAC_CAM_MODE_TWO                  4
#define MAC_EIGHT_GROUP_YC                5
#define MAC_CAM_MOTOR_YS                  6
#define MAC_EIGHT_GROUP2_XZQ              7
#define MAC_FY_3G_DOUBLE                  8
#define MAC_FY_DOUBLE                     9
#define MAC_SINGLE_NORMAL                 10
#define MAC_SINGLE_CAM_MOTOR              11
#define MAC_EIGHT_GROUP3_XZQ              12
#define MAC_FY_DOUBLE_JT                  13
#define MAC_TYPE                          12


/*
 * Func: GetFlowerLine
 * Para: [in] type:  7   6   5   4   3   2   1   0
 *                  2BH 2BA 2FH  2FA 1BH 1BA 1FH 1FA
 *       [in] rock: needle of rock
 *       [in] line: start from 1 for flower
 *       [in] mrow: start from 0
 * Retu: NONE
 * Desc: put flower data into one line
 * Auth: wzwz
 * Time: 2012.03.22
 */
static void GetFlwSendLine(MH_KNIT *p, uchar *out, int size,
        int line, char act, int code, int type, int rock, int prefix, int mrow)
{
    uchar *flw = NULL;
    if(prefix)
    {
        /* 前缀编织数据 */
        if(line > 0 && line <= p->pk_data.ppat.rows)
        {
            flw = &p->pk_data.ppat.buf[p->pk_data.pat_width * (line - 1)];
        }
        else
        {
            printf("%s %d: no prefix flower data: %d\n", __FILE__, __LINE__, line);
        }
    }
    else if(line > 0 && line <= GetFlowerHeight(p))
    {
        flw = GetFlowerLine(p, line);
    }
    if(!flw)
    {
        return;
    }
    int i = 0;
    int s = 0;
    int e = GetFlowerWidth(p);
    if(prefix)
    {
        e = p->pk_data.pat_width;
    }
    if(p->knit_state.bp_enable)
    {
        if(p->done_cloth + 1 < p->total_cloth)
        {
            if(mrow + 1 > backpiece_get_end_row(p))
            {
                PAT_RANGE range;
                backpiece_get_first_row_range(p, &range);
                s = range.pat_start;
                e = range.pat_end + 1;
            }
        }
    }
    for(i = s; i < e; i++)
    {
        if(flw[i] != 0x0F)
        {
            int n = 1 << flw[i];
            int pos = i;
            if(n & code)
            {
                if(act == 0x04 || act == 0x06 || act == 0x07 || act == 0x10)
                {
                    switch(type)
                    {
                    case 1:
                        pos -= rock;
                        break;
                    case 3:
                        pos += rock;
                        break;
                    case 5:
                        pos -= rock;
                        break;
                    case 7:
                        pos += rock;
                        break;
                    }
                }
                if(pos > -1 && pos < size)
                {
                    out[pos] |= 1 << type;
                }
            }
        }
    }
}
/*
 *
 */
static inline int IsActKnit(uchar act)
{
    if((act) == MH_ACT_KNIT_RECV || (act) == MH_ACT_KNIT_TRAN)
    {
        return TRUE;
    }
    if((act) == MH_ACT_KNIT || (act) == MH_ACT_TUCK)
    {
        return TRUE;
    }
    if((act) == MH_ACT_KNIT_RUDE || (act) == MH_ACT_KNIT_TUCK)
    {
        return TRUE;
    }
    return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// Func: HasTransfer
// para: conline -- data of conline
// Retu: int --- 1=YES 0=FALSE
// Desc: check transfer act this line
// Auth: wzwz
// Time: 2012.05.25
///////////////////////////////////////////////////////////////////////////////
static int HasTransfer(KNIT_PAGE *conline)
{
    int i, j;
    uchar act[2][2];
    act[0][0] = conline->act_1FA | conline->act_1FH;
    act[0][1] = conline->act_1BA | conline->act_1BH;
    act[0][2] = conline->act_2FA | conline->act_2FH;
    act[0][3] = conline->act_2BA | conline->act_2BH;
    for(i = 0; i < 2; ++i)
    {
        for(j = 0; j < 2; ++j)
        {
            if(act[i][j] == MH_ACT_TRANSFER)
            {
                return TRUE;
            }
            if(act[i][j] == MH_ACT_TRAN_RECV)
            {
                return TRUE;
            }
            if(act[i][j] == MH_ACT_KNIT_TRAN)
            {
                return TRUE;
            }
        }
    }
    return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// Func: GetSanjiaoState                                    7
// Para: [in] act                                      6         5
//       [in] dir -- direction 0f machine   0=R 1=L    4    3    2
// Retu: char -- state
// Desc: convert act to state of sanjiao
// Auth: wzwz
// Time: 2012.03.22
///////////////////////////////////////////////////////////////////////////////
static char GetSanjiaoState(MH_KNIT *p, char act, char dir)
{
    char state = 0;
    if(p->sys_info.cam == 1)
    {
        switch(act)
        {
        case MH_ACT_TRANSFER:
            if(p->sys_info.mac == MAC_SINK_FOR_CAM)
            {
                state = 0x14;
            }
            else if(p->sys_info.mac == MAC_CAM_MODE_TWO)
            {
                state = 0xD4;
            }
            else if(p->sys_info.mac == MAC_SINGLE_NORMAL)
            {
                state = 0x80;
            }
            else
            {
                state = 0x9C;
            }
            break;
        case MH_ACT_RECEIVE:
            if(p->sys_info.mac == MAC_SINK_FOR_CAM)
            {
                state = 0x14;
            }
            else if(p->sys_info.mac == MAC_CAM_MODE_TWO)
            {
                state = dir ? 0x04 : 0x10;
            }
            else if(p->sys_info.mac == MAC_SINGLE_NORMAL)
            {
                state = 0x88;
            }
            else if(p->sys_info.mac == MAC_EIGHT_GROUP_YC && p->sys_info.rsvd == 1)//盛星宏星
            {
                state = 0x14;
            }
            else
            {
                state = dir ? 0x04 : 0x10;
                if(p->tran_cam_state)
                {
                    state |= 0x80;
                }
            }
            break;
        case MH_ACT_KNIT:
            if(p->sys_info.mac == MAC_SINK_FOR_CAM)
            {
                state = 0x14;
            }
            else if(p->sys_info.mac == MAC_CAM_MODE_TWO)
            {
                state = 0x1C;
            }
            else if(p->sys_info.mac == MAC_SINGLE_NORMAL)
            {
                state = 0x00;
            }
            else
            {
                state = 0x1C;
            }
            break;
        case MH_ACT_TUCK:
            if(p->sys_info.mac == MAC_SINK_FOR_CAM)
            {
                state = 0x14;
            }
            else if(p->sys_info.mac == MAC_CAM_MODE_TWO)
            {
                state = 0x14;
            }
            else if(p->sys_info.mac == MAC_SINGLE_NORMAL)
            {
                state = 0x14;
            }
            else
            {
                state = 0x14;
            }
            break;
        case MH_ACT_KNIT_TRAN:
            if(p->sys_info.mac == MAC_SINGLE_NORMAL)
            {
                state = 0x88;
            }
            else
            {
                state = 0x9C;
            }
            break;
        case MH_ACT_JI:
            if(p->sys_info.mac == MAC_CAM_MODE_TWO)
            {
                state = dir ? 0x50 : 0x84;
            }
            break;
        case MH_ACT_TRAN_RECV:
            if(p->sys_info.mac == MAC_EIGHT_GROUP_YC && p->sys_info.rsvd == 1)//盛星宏星
            {
                state = 0x94;
            }
            else if(p->sys_info.mac == MAC_EIGHT_GROUP_YC)
            {
                state = dir ? 0x8C : 0x98;
            }
            else if(p->sys_info.mac == MAC_SINGLE_NORMAL)
            {
                state = 0x88;
            }
            else
            {
                state = 0x9C;
            }
            break;
        case MH_ACT_KNIT_TUCK:
            if(p->sys_info.mac == MAC_EIGHT_GROUP_YC)
            {
                state = 0x14;
            }
            break;
        default:
            break;
        }
    }
    else
    {
        switch(act)
        {
        case MH_ACT_TRANSFER://tran
            state = 0x80;
            break;
        case MH_ACT_RECEIVE://recv
        case MH_ACT_TRAN_RECV://tran and recv
            state = 0x88;
            if(p->knit_state.tran_dumu_enable)
            {
                if(dir == 0)//right
                {
                    state = 0x98;
                }
                else
                {
                    state = 0x8C;
                }
            }
            break;
        case MH_ACT_KNIT_RECV://knit and recv
            state = 0x88;
            break;
        case MH_ACT_KNIT://knit
            state = 0x00;
            break;
        case MH_ACT_TUCK://tuck
            state = 0x14;
            break;
        case MH_ACT_KNIT_RUDE://knit and rude
            if(dir == 0)//right
            {
                state = 0x3C;
            }
            else
            {
                state = 0x5C;
            }
            break;
        case MH_ACT_KNIT_TUCK://knit and tuck
            state = 0x14;
            break;
        case MH_ACT_KNIT_TRAN://knit and tran
            state = 0x88;
            break;
        }
    }
    return state;
}
/*
 * clip off
 */
static uchar GetClipOff(MH_KNIT *p, uchar clip)
{
    uchar ret  =0;
    if(clip & 1)
    {
        ret |= 0x01;
        p->board_state.clip_off[0] = TRUE;
    }
    if(clip & 2)
    {
        ret |= 0x04;
        p->board_state.clip_off[1] = TRUE;
    }
    if(clip & 4)
    {
        ret |= 0x10;
        p->board_state.clip_off[2] = TRUE;
    }
    if(clip & 8)
    {
        ret |= 0x40;
        p->board_state.clip_off[3] = TRUE;
    }
    return ret;
}
/*
 * clip on
 */
static uchar GetClipOn(MH_KNIT *p, uchar clip)
{
    uchar ret = 0;
    if(p->board_state.clip_off[0] && (clip & 1))
    {
        ret |= 0x02;
        p->board_state.clip_off[0] = FALSE;
    }
    if(p->board_state.clip_off[1] && (clip & 2))
    {
        ret |= 0x08;
        p->board_state.clip_off[1] = FALSE;
    }
    if(p->board_state.clip_off[2] && (clip & 4))
    {
        ret |= 0x20;
        p->board_state.clip_off[2] = FALSE;
    }
    if(p->board_state.clip_off[3] && (clip & 8))
    {
        ret |= 0x80;
        p->board_state.clip_off[3] = FALSE;
    }
    return ret;
}
/*
 *
 */
static int GetDumuF1(MH_KNIT *p, uchar mac_dir, uchar act_1F, uchar act_2F,
        uchar dumu1_sect, uchar dumu2_sect, uchar dmbz_sect, int dumu_comp)
{
    int dumu = 0;
    enum {RIGHT = 0, LEFT = 1};
    if(TRUE)
    {
        if(mac_dir == RIGHT)
        {
            uchar sect = p->sys_info.cam == 1 ? dumu1_sect : dumu2_sect;
            dumu = GetRunDumu(p, 0, sect - 1, 0);
            dumu += GetSingleDmbz(p, 0, 0);
        }
        dumu = __max(0, dumu);
    }
    //printf("dumuF1: %d\n", dumu);
    return dumu;
}
/*
 *
 */
static int GetDumuB1(MH_KNIT *p, uchar mac_dir, uchar act_1B, uchar act_2B, uchar dumu1_sect, uchar dumu2_sect, uchar dmbz_sect, int dumu_comp)
{
    int dumu = 0;
    enum {RIGHT = 0, LEFT = 1};
    if(TRUE)
    {
        if(mac_dir == RIGHT)
        {
            uchar sect = p->sys_info.cam == 1 ? dumu1_sect : dumu2_sect;
            dumu = GetRunDumu(p, 1, sect - 1, 0);
            dumu += GetSingleDmbz(p, 1, 0);
        }
        dumu = __max(0, dumu);
    }
    //printf("dumuB1: %d\n", dumu);
    return dumu;
}
/*
 *
 */
static int GetDumuF2(MH_KNIT *p, uchar mac_dir, uchar act_1F, uchar act_2F, uchar dumu1_sect, uchar dumu2_sect, uchar dmbz_sect, int dumu_comp)
{
    int dumu = 0;
    enum {RIGHT = 0, LEFT = 1};
    if(TRUE)
    {
        if(mac_dir == LEFT)
        {
            uchar sect = dumu1_sect;
            dumu = GetRunDumu(p, 0, sect - 1, 1);
            dumu += GetSingleDmbz(p, 0, 1);
        }
        dumu = __max(0, dumu);
    }
    //printf("dumuF2: %d\n", dumu);
    return dumu;
}
/*
 *
 */
static int GetDumuB2(MH_KNIT *p, uchar mac_dir, uchar act_1B, uchar act_2B, uchar dumu1_sect, uchar dumu2_sect, uchar dmbz_sect, int dumu_comp)
{
    int dumu = 0;
    enum {RIGHT = 0, LEFT = 1};
    if(TRUE)
    {
        if(mac_dir == LEFT)
        {
            uchar sect = dumu1_sect;
            dumu = GetRunDumu(p, 1, sect - 1, 1);
            dumu += GetSingleDmbz(p, 1, 1);
        }
        dumu = __max(0, dumu);
    }
    //printf("dumuB2: %d\n", dumu);
    return dumu;
}
/*
 *
 */
static int GetDumuF3(MH_KNIT *p, uchar mac_dir, uchar act_1F, uchar act_2F, uchar dumu1_sect, uchar dumu2_sect, uchar dmbz_sect, int dumu_comp)
{
    int dumu = 0;
    enum {RIGHT = 0, LEFT = 1};
    if(TRUE)
    {
        if(mac_dir == RIGHT)
        {
            uchar sect = dumu1_sect;
            dumu = GetRunDumu(p, 0, sect - 1, 2);
            dumu += GetSingleDmbz(p, 0, 2);
        }
        dumu = __max(0, dumu);
    }
    return dumu;
}
/*
 *
 */
static int GetDumuB3(MH_KNIT *p, uchar mac_dir, uchar act_1B, uchar act_2B, uchar dumu1_sect, uchar dumu2_sect, uchar dmbz_sect, int dumu_comp)
{
    int dumu = 0;
    enum {RIGHT = 0, LEFT = 1};
    if(TRUE)
    {
        if(mac_dir == RIGHT)
        {
            uchar sect = dumu1_sect;
            dumu = GetRunDumu(p, 1, sect - 1, 2);
            dumu += GetSingleDmbz(p, 1, 2);
        }
        dumu = __max(0, dumu);
    }
    return dumu;
}
/*
 *
 */
static int GetDumuF4(MH_KNIT *p, uchar mac_dir, uchar act_1F, uchar act_2F, uchar dumu1_sect, uchar dumu2_sect, uchar dmbz_sect, int dumu_comp)
{
    int dumu = 0;
    enum {RIGHT = 0, LEFT = 1};
    if(TRUE)
    {
        if(mac_dir == LEFT)
        {
            uchar sect = dumu2_sect;
            dumu = GetRunDumu(p, 0, sect - 1, 3);
            dumu += GetSingleDmbz(p, 0, 3);
        }
        dumu = __max(0, dumu);
    }
    return dumu;
}
/*
 *
 */
static inline int GetDumuB4(MH_KNIT *p, uchar mac_dir, uchar act_1B, uchar act_2B, uchar dumu1_sect, uchar dumu2_sect, uchar dmbz_sect, int dumu_comp)
{
    int dumu = 0;
    enum {RIGHT = 0, LEFT = 1};
    if(TRUE)
    {
        if(mac_dir == LEFT)
        {
            uchar sect = dumu2_sect;
            dumu = GetRunDumu(p, 1, sect - 1, 3);
            dumu += GetSingleDmbz(p, 1, 3);
        }
        dumu = __max(0, dumu);
    }
    return dumu;
}
/*
 *
 */
static void GetDumuData(MH_KNIT *p, uchar *data, uchar drt,
        uchar act_1F, uchar act_2F, uchar act_1B, uchar act_2B,
        uchar sect1, uchar sect2, uchar dmbz)
{
    //dumu data
    int dumu_comp = 300;
    if(p->sys_info.mac == MAC_EIGHT_GROUP2_XZQ || p->sys_info.mac
            == MAC_EIGHT_GROUP3_XZQ)
    {
        dumu_comp = p->dumu_com;
    }
    int dumu = 0;
    //front1
    dumu = GetDumuF1(p, drt, act_1F, act_2F, sect1, sect2, dmbz, dumu_comp);
    data[40] = dumu & 0xFF;
    data[41] = (dumu >> 8) & 0xFF;
    //back1
    dumu = GetDumuB1(p, drt, act_1B, act_2B, sect1, sect2, dmbz, dumu_comp);
    data[42] = dumu & 0xFF;
    data[43] = (dumu >> 8) & 0xFF;
    //front2
    dumu = GetDumuF2(p, drt, act_1F, act_2F, sect1, sect2, dmbz, dumu_comp);
    data[44] = dumu & 0xFF;
    data[45] = (dumu >> 8) & 0xFF;
    //back2
    dumu = GetDumuB2(p, drt, act_1B, act_2B, sect1, sect2, dmbz, dumu_comp);
    data[46] = dumu & 0xFF;
    data[47] = (dumu >> 8) & 0xFF;
    //front 3
    dumu = GetDumuF3(p, drt, act_1F, act_2F, sect1, sect2, dmbz, dumu_comp);
    data[48] = dumu & 0xFF;
    data[49] = (dumu >> 8) & 0xFF;
    //back3
    dumu = GetDumuB3(p, drt, act_1B, act_2B, sect1, sect2, dmbz, dumu_comp);
    data[50] = dumu & 0xFF;
    data[51] = (dumu >> 8) & 0xFF;
    //front4
    dumu = GetDumuF4(p, drt, act_1F, act_2F, sect1, sect2, dmbz, dumu_comp);
    data[52] = dumu & 0xFF;
    data[53] = (dumu >> 8) & 0xFF;
    //back4
    dumu = GetDumuB4(p, drt, act_1B, act_2B, sect1, sect2, dmbz, dumu_comp);
    data[54] = dumu & 0xFF;
    data[55] = (dumu >> 8) & 0xFF;
}
/*
 * sect start from 0
 */
int sink_get_data(MH_KNIT *p, uchar sect, uchar act1, uchar act2, uchar l1r0, uchar f0b1)
{
    int ret = 0;
    if(act1 == MH_ACT_KNIT_RECV || act1 == MH_ACT_KNIT || act1 == MH_ACT_TUCK
            || act1 == MH_ACT_KNIT_RUDE || act1 == MH_ACT_KNIT_TUCK
            || act1 == MH_ACT_KNIT_TRAN || act2 == MH_ACT_KNIT_RECV
            || act2 == MH_ACT_KNIT || act2 == MH_ACT_TUCK || act2 == MH_ACT_KNIT_RUDE
            || act2 == MH_ACT_KNIT_TUCK || act2 == MH_ACT_KNIT_TRAN)//knit
    {
        if(f0b1 == 0)//front
        {
            if(l1r0)
            {
                ret = p->sink_value[sect][0];
            }
            else
            {
                ret = p->sink_value[sect][4];
            }
        }
        else//back
        {
            if(l1r0)
            {
                ret = p->sink_value[sect][1];
            }
            else
            {
                ret = p->sink_value[sect][5];
            }
        }
    }
    else if(act1 == MH_ACT_TRANSFER || act1 == MH_ACT_RECEIVE || act1 == MH_ACT_TRAN_RECV
       || act2 == MH_ACT_TRANSFER || act2 == MH_ACT_RECEIVE || act2 == MH_ACT_TRAN_RECV)
    {
        if(f0b1 == 0)//front
        {
            if(l1r0)
            {
                ret = p->sink_value[sect][2];
            }
            else
            {
                ret = p->sink_value[sect][6];
            }
        }
        else//back
        {
            if(l1r0)
            {
                ret = p->sink_value[sect][3];
            }
            else
            {
                ret = p->sink_value[sect][7];
            }
        }
    }
    return ret;
}
/*
 *
 */
static int GetCamSinkState(const char act, const char l1r0, const char f0b1)
{
    int state = 0;
    switch(act)
    {
    case MH_ACT_TRANSFER:
        {
            state = /*f0b1 ? 1 : */4;
        }
        break;
    case MH_ACT_RECEIVE:
        if(f0b1)//back
        {
            //state = l1r0 ? 4 : 2;
            state = l1r0 ? 1 : 3;
        }
        else
        {
            state = l1r0 ? 3 : 1;
        }
        break;
    case MH_ACT_KNIT:
        {
            state = 0;
        }
        break;
    case MH_ACT_TUCK:
        {
            state = /*f0b1 ? 3 : */2;
        }
        break;
    default:
        break;
    }
    if (act != MH_ACT_KNIT)
        {
            /* 华伦巨星与宇辰相反 */
            //if (g_comp_info.sys == 1)
            {
                state = 5 - state;
            }

        }
    return state;
}
/*
 * start from 1
 */
static int GetFrontSink(MH_KNIT *p, uchar mac_dir, uchar act_1F, uchar act_2F, uchar sect, uchar f0b1)
{
    int sink = 0;
    if(sect > 1 && sect < 11)
    {
        --sect;
    }
    else
    {
        sect = 0;
    }
    if(p->sys_info.mac == MAC_SINK_FOR_CAM && p->sys_info.cam == 1)
    {
        sink = GetCamSinkState(act_1F, mac_dir, FALSE);
    }
    else if(p->sink_enable)
    {
        sink = sink_get_data(p, sect, act_1F, act_2F, mac_dir, f0b1);
    }
    return sink;
}
/*
 *
 */
static int GetBackSink(MH_KNIT *p, uchar mac_dir, uchar act_1B, uchar act_2B, uchar sect, uchar f0b1)
{
    int sink = 0;
    if(sect > 1 && sect < 11)
    {
        --sect;
    }
    else
    {
        sect = 0;
    }
    if(p->sys_info.mac == MAC_SINK_FOR_CAM && p->sys_info.cam == 1)
    {
        sink = GetCamSinkState(act_1B, mac_dir, TRUE);
    }
    else if(p->sink_enable)
    {
        sink = sink_get_data(p, sect, act_1B, act_2B, mac_dir, f0b1);
    }
    return sink;
}
/*
 * sect: start from 1
 */
static void GetSinkData(MH_KNIT *p, uchar *data, uchar drt,
        uchar act_1F, uchar act_2F, uchar act_1B, uchar act_2B,
        uchar act_3F, uchar act_4F, uchar act_3B, uchar act_4B,
        uchar sect)
{
    int sink_f = GetFrontSink(p, drt, act_1F, act_2F, sect, FALSE);
    int sink_b = GetBackSink(p, drt, act_1B, act_2B, sect, TRUE);
    if(p->sys_info.mac == MAC_NORMAL || p->sys_info.mac == MAC_FY_DOUBLE_JT)
    {
        //keep instance when one sink is zero
        if(!sink_f)
        {
            sink_f = sink_b;
        }
        if(!sink_b)
        {
            sink_b = sink_f;
        }
    }
    else if(p->sys_info.mac == MAC_EIGHT_GROUP3_XZQ)
    {
        if(act_1F == MH_ACT_KNIT_TRAN)
        {
            sink_b = sink_f;
        }
        else if(act_1B == MH_ACT_KNIT_TRAN)
        {
            sink_f = sink_b;
        }
    }
    data[72] = sink_f & 0xFF;
    data[73] = (sink_f >> 8) & 0xFF;
    data[74] = sink_b & 0xFF;
    data[75] = (sink_b >> 8) & 0xFF;//sink end
    //printf("sink: %d, %d\n", sink_f, sink_b);
    if(p->sys_info.cam == 1 && p->sys_info.mac == MAC_SINK_FOR_CAM)
    {
        /* 第二次三角，用于三角款机器 */
        sink_f = GetFrontSink(p, drt, act_3F, act_4F, sect, FALSE);
        sink_b = GetBackSink(p, drt, act_3B, act_4B, sect, TRUE);

        data[76] = sink_f & 0xFF;
        data[77] = (sink_f >> 8) & 0xFF;
        data[78] = sink_b & 0xFF;
        data[79] = (sink_b >> 8) & 0xFF;//sink end
    }
    else if(p->sys_info.mac == MAC_DOUBLE_JITOU || p->sys_info.mac == MAC_FY_DOUBLE_JT)
    {
        sink_f = GetFrontSink(p, drt, act_1F, act_2F, sect, 1);
        sink_b = GetBackSink(p, drt, act_1B, act_2B, sect, 1);
        if(p->sys_info.mac == MAC_FY_DOUBLE_JT)
        {
            //keep instance when one sink is zero
            if(!sink_f)
            {
                sink_f = sink_b;
            }
            if(!sink_b)
            {
                sink_b = sink_f;
            }
        }
        data[76] = sink_f & 0xFF;
        data[77] = (sink_f >> 8) & 0xFF;
        data[78] = sink_b & 0xFF;
        data[79] = (sink_b >> 8) & 0xFF;
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Func: GetYarnEndPoint
// Para: [in] data  -- flower data
//       [in] start -- start of data (1 start)
//       [in] end   -- end of data (1 start)
//       [in] act   -- front act
//       [in] type  -- type of act            ---3   1-->    <--1  3---
//                                            ---2   0-->    <--0  2---
//       [in] dir   -- direction of machine 1=L 0=R
// Retu: int -- end point of yarn off(1 start)
// Desc: get off point of yarn
// Auth: wzwz
// Time: 2012.03.23
//////////////////////////////////////////////////////////////////////////////////////////////
static int GetYarnEndPoint(uchar *data, int start, int end, char act, char type, char dir)
{
    char tuck[4] = {0x02, 0x08, 0x20, 0x80};
    char knit[4] = {0x01, 0x04, 0x10, 0x40};
    int tuck_pos = 0;
    int knit_pos = 0;
    int ret = 0;
    int i = 0;
    if(act == MH_ACT_TUCK || MH_ACT_KNIT_TUCK)//tuck
    {
        for(i = start - 1; i < end; i++)
        {
            if(data[i] & tuck[(int)type])
            {
                tuck_pos = i + 1;
                if(dir)//left
                {
                    break;
                }
            }
        }
    }
    if(act == MH_ACT_KNIT_RECV || act == MH_ACT_KNIT || act == MH_ACT_KNIT_RUDE ||
            act == MH_ACT_KNIT_TUCK || act == MH_ACT_KNIT_TRAN)//knit
    {
        for(i = start - 1; i < end; i++)
        {
            if(data[i] & knit[(int)type])
            {
                knit_pos = i + 1;
                if(dir)//left
                {
                    break;
                }
            }
        }
    }
    if(dir)//left
    {
        if(tuck_pos)
        {
            if(knit_pos)
            {
                ret = __min(tuck_pos, knit_pos);
            }
            else
            {
                ret = tuck_pos;
            }
        }
        else
        {
            ret = knit_pos;
        }
    }
    else//right
    {
        ret = __max(tuck_pos, knit_pos);
    }
    return ret;
}
////////////////////////////////////////////////////////////////////////////
// Func: GetYarnCodeEnd
// Para: [in] line -- line of flower(1 start)
//       [in] type -- 0=right of end  1=left of end
// Retu: int -- end position of yarn code(15)
// Desc: get the end position of 15(yarn code)
// Auth: wzwz
// Time: 2012.02.23
////////////////////////////////////////////////////////////////////////////
static int GetYarnCodeEnd(MH_KNIT *p, int line, char type)
{
    int ret = 0;
    uchar *flw = GetFlowerLine(p, line);
    if(!flw)
    {
        return ret;
    }
    int width = GetFlowerWidth(p);
    int start = type ? 0 : width - 1;
    int end = type ? width : -1;
    int delta = type ? 1 : -1;
    while(start != end)
    {
        if(flw[start] == 0x0F)
        {
            ret = start + 1;
            break;
        }
        start += delta;
    }
    return ret;
}
/*
 * 获取双系统16把纱嘴嵌花导精模式
 */
int GetYintaPosSeiki(KNIT_PAGE* curt_conline, int flw_line, int system, int yarn, int dirt)
{
#if 0
    int pos[2][GAUZE_NUM] = {{0}};
    int w = 0, j = 0;
    int width_dat = comm_data(COMM_GET_FLOWER_WIDTH, NULL);//flower_getwidth();
    uchar *flower_data = (uchar*)comm_data(COMM_GET_FLOWER_POINTER, NULL);
    for(w = 0; w < width_dat; w++)
    {
        uchar cc = flower_data[(flw_line - 1) * width_dat + w];
        if(cc == 0x0F)//带纱嘴符号
        {
            if(!pos[0][j])
            {
                pos[0][j] = w + 1;
            }
            else
            {
                pos[1][j] = w + 1;
                j++;
            }
        }
        if(j > GAUZE_NUM - 1)
        {
            break;
        }
    }
    int index[16] = {5, 15, 25, 35, 45, 55, 65, 75, 9, 19, 29, 39, 49, 59, 69, 79};
    int k = 0;
    int base = system == 1 ? 0 : 8;
    if(yarn == 1)
    {
        k = (curt_conline[121] & 0x7F) - (system == 1 ? 1 : 9);
    }
    else
    {
        //导精同一个纱嘴并列带2次
        if(dirt)
        {
            for(k = 0; k < 8; k++)
            {
                //DEBUG_OUT("%X  ", curt_conline[index[base + k]]);
                if(curt_conline[index[base + k]] == yarn - 1)
                {
                    //DEBUG_OUT("%X-%X  ", curt_conline[index[base + k]], base + k);
                    break;
                }
            }
        }
        else
        {
            for(k = 7; k >= 0; k--)
            {
                if(curt_conline[index[base + k]] == yarn - 1)
                {
                    //DEBUG_OUT("%X-%X  ", curt_conline[index[base + k]], pos[1][k]);
                    break;
                }
            }
        }
    }
    //DEBUG_OUT("flw_line: %d, %d, %d, %d\n", flw_line, yarn, j, k);
    if(k > -1 && k < j)
    {
        return pos[dirt ? 0 : 1][k];
    }
#endif
    return 1;
}
/*
 * 获取双系统16把纱嘴嵌花模式
 */
int GetYintaPos(MH_KNIT *p, KNIT_PAGE* curt_conline, int flw_line, int system, int yarn, int dirt)
{
    int pos[2][GAUZE_NUM] = {{0}};
    int w = 0, j = 0;
    uchar *flw = GetFlowerLine(p, flw_line);
    if(flw)
    {
        int width_dat = GetFlowerWidth(p);
        for(w = 0; w < width_dat; w++)
        {
            if(flw[w])
            {
                if(!pos[0][j])
                {
                    pos[0][j] = w + 1;
                }
                if(w == width_dat - 1)
                {
                    if(pos[0][j])
                    {
                        pos[1][j] = w + 1;
                        j++;
                    }
                }
            }
            if(!flw[w])
            {
                if(pos[0][j])
                {
                    pos[1][j] = w;
                    j++;
                }
            }
            if(j > GAUZE_NUM - 1)
            {
                break;
            }
        }
    }
    uchar gauze[2][8];
    gauze[0][0] = curt_conline->gauze_11;
    gauze[0][1] = curt_conline->gauze_12;
    gauze[0][2] = curt_conline->gauze_13;
    gauze[0][3] = curt_conline->gauze_14;
    gauze[0][4] = curt_conline->gauze_15;
    gauze[0][5] = curt_conline->gauze_16;
    gauze[0][6] = curt_conline->gauze_17;
    gauze[0][7] = curt_conline->gauze_18;
    gauze[1][0] = curt_conline->gauze_21;
    gauze[1][1] = curt_conline->gauze_22;
    gauze[1][2] = curt_conline->gauze_23;
    gauze[1][3] = curt_conline->gauze_24;
    gauze[1][4] = curt_conline->gauze_25;
    gauze[1][5] = curt_conline->gauze_26;
    gauze[1][6] = curt_conline->gauze_27;
    gauze[1][7] = curt_conline->gauze_28;
    int k = 0;
    if(yarn == 1)
    {
        k = (curt_conline->yinta & 0x7F) - (system == 1 ? 1 : 9);
    }
    else
    {
        for(k = 0; k < 8; k++)
        {
            //DEBUG_OUT("%X  ", curt_conline[index[base + k]]);
            if(gauze[system - 1][k] == yarn - 1)
            {
                break;
            }
        }
    }
    //DEBUG_OUT("yintapos: %d, %d, %d\n", k, pos[0][j - k - 1], pos[1][k]);
    if(dirt)//left
    {
        if(j > k)
        {
            return pos[0][j - k - 1];
        }
        else
        {
            return 1;
        }
    }
    return pos[1][k];
}
///////////////////////////////////////////////////////////////////
// Func: GetRockPulse
// Para: [in] low  -- low byte of rock
//       [in] hign -- high byte of rock
//       [in] tran -- 1=has transfer 0=no
// Retu: int -- pulse of rock
// Desc: get the pulse of rock
// Auth: wzwz
// Time: 2012.03.23
///////////////////////////////////////////////////////////////////
int GetRockPulse(MH_KNIT *p, uint drt, uint needle, uint tran, uint flag)
{
    int ret = 0;
    enum {STAR = 1};

    float inch_type = 12;
    if(p->inch_type > 0.4)
    {
        inch_type = p->inch_type;
    }
    uint silk_per_needle = MM_PER_INCH * 100 / inch_type;

    if(tran)
    {
        if(needle == 0)
        {
            ret = p->rock_right_tran_com[0];
        }
        else
        {
            if(drt == ROCK_RIGHT)
            {
                ret = p->rock_right_tran_com[needle] + p->rock_right_tran_com[0];
                ret += silk_per_needle * needle;
            }
            else
            {
                ret = p->rock_left_tran_com[needle] + p->rock_right_tran_com[0];
                ret -= silk_per_needle * needle;
            }
        }
    }
    else if(flag == STAR)//*
    {
        if(needle == 0)
        {
            ret = p->rock_right_star_com[0] + p->rock_star;
        }
        else
        {
            if(drt == ROCK_RIGHT)
            {
                ret = p->rock_right_star_com[needle] + p->rock_star;
                ret += silk_per_needle * needle;
            }
            else
            {
                ret = p->rock_left_star_com[needle] + p->rock_star;
                ret -= silk_per_needle * needle;
            }
        }
    }
    else
    {
        if(needle > 0)
        {
            if(drt == ROCK_RIGHT)
            {
                ret = p->rock_right_com[needle];
                ret += silk_per_needle * needle;
            }
            else
            {
                ret = p->rock_left_com[needle];
                ret -= silk_per_needle * needle;
            }
        }
    }
    if(GetRockType(p) == ROCK_FRONT_BACK)
    {
        ret /= 2;
    }
    ret *= GetRockPulsePerSilk(p);
    return ret;
}
/*
 * 摇床抖动
 *
 */
static int GetRockShake(MH_KNIT *p, uint shake)
{
    if(shake == ROCK_SHAKE_NONE)
    {
        return 0;
    }
    int ret = 0;
    float inch_type = 12;
    if(p->inch_type)
    {
        inch_type = p->inch_type;
    }
    int cell = CM_PER_INCH * 1000.0 / inch_type * GetRockPulsePerSilk(p);
    if(shake == ROCK_SHAKE_HALF)
    {
        ret = cell / 2;
    }
    else if(shake == ROCK_SHAKE)
    {
        ret = cell;
    }
    return ret;
}
/*
 *
 */
int MoveStartPoint(MH_KNIT *p, uchar *data)
{
    int ret = 0;
    int n = p->start_needle;
    n -= p->left_bound;
    if(n < p->total_needle)
    {
        int s = 0;
        int i = 0;
        uchar tmp[1600] = {0};
        memcpy(tmp, data, 1600);
        memset(data, 0, 1600);

        s = n;
        for(i = 0; i < 1600; i++)
        {
            if((s >= 1) && (s <= 1600))
            {
                data[s - 1] = tmp[i];
            }
            s++;
        }

        ret = n - 1;
    }
    return ret;
}
////////////////////////////////////////////////////////////////////////////
// Func: GetRetLen
// Para: [in] data   -- flower data
//       [in] system -- 0=sys1 1=sys2
//       [in] type   -- 0=right 1=left
// Retu: int -- end position of needle
// Desc: get the end position of needle
// Auth: wzwz
// Time: 2012.03.23
////////////////////////////////////////////////////////////////////////////
static int GetRetLen(uchar *data, int size, char system, char type)
{
    int ret = -1;
    int n = system ? 0xF0 : 0x0F;
    int i = 0;
    for(i = 0; i < size; i++)
    {
        if(data[i] & n)
        {
            ret = i + 1;
            if(type)//left
            {
                break;
            }
        }
    }
    //printf("ret %d %d\n", size, ret);
    return ret;
}
/*
 * @data: 发给下位机的数据缓冲区
 * @curt_conline: 控制数据缓冲区
 * @compress: 是否是压缩行
 * @NOTE:压缩行的第二行数据，放在系统3，系统4上，摇床放在113，117位置
 */
void CompressFlw(MH_KNIT *p, int line, uchar *data, uint size, KNIT_PAGE *pcurt_conline, int prefix)
{
    //3rd-front
    int cur_row_3F = pcurt_conline->flw_3F;
    char cur_act_3FA = pcurt_conline->act_3FA;
    int cur_code_3FA = pcurt_conline->code_3FA;
    char cur_act_3FH = pcurt_conline->act_3FH;
    int cur_code_3FH = pcurt_conline->code_3FH;
    //3rd-back
    int cur_row_3B = pcurt_conline->flw_3B;
    char cur_act_3BA = pcurt_conline->act_3BA;
    int cur_code_3BA = pcurt_conline->code_3BA;
    char cur_act_3BH = pcurt_conline->act_3BH;
    int cur_code_3BH = pcurt_conline->code_3BH;

    char cur_act_3F = cur_act_3FA ? cur_act_3FA : cur_act_3FH;
    char cur_act_3B = cur_act_3BA ? cur_act_3BA : cur_act_3BH;

    //4th-front
    int cur_row_4F = pcurt_conline->flw_4F;
    char cur_act_4FA = pcurt_conline->act_4FA;
    int cur_code_4FA = pcurt_conline->code_4FA;
    char cur_act_4FH = pcurt_conline->act_4FH;
    int cur_code_4FH = pcurt_conline->code_4FH;
    //4th-back
    int cur_row_4B = pcurt_conline->flw_4B;
    char cur_act_4BA = pcurt_conline->act_4BA;
    int cur_code_4BA = pcurt_conline->code_4BA;
    char cur_act_4BH = pcurt_conline->act_4BH;
    int cur_code_4BH = pcurt_conline->code_4BH;

    char cur_act_4F = cur_act_4FA ? cur_act_4FA : cur_act_4FH;
    char cur_act_4B = cur_act_4BA ? cur_act_4BA : cur_act_4BH;


    int c_rock = pcurt_conline->rock2_num.needle;
    if(pcurt_conline->rock2_dir.drt == ROCK_LEFT)
    {
        c_rock = -c_rock;
    }
    //flower data
    enum
    {
        ACT_1FA = 0,
        ACT_1FH = 1,
        ACT_1BA = 2,
        ACT_1BH = 3,
        ACT_2FA = 4,
        ACT_2FH = 5,
        ACT_2BA = 6,
        ACT_2BH = 7
    };
    if(cur_row_3F)
    {
        GetFlwSendLine(p, data, size, cur_row_3F, cur_act_3F,
                cur_code_3FA, ACT_1FA, c_rock, prefix, line);
        GetFlwSendLine(p, data, size, cur_row_3F, cur_act_3F,
                cur_code_3FH, ACT_1FH, c_rock, prefix, line);
    }
    if(cur_row_3B)
    {
        GetFlwSendLine(p, data, size, cur_row_3B, cur_act_3B,
                cur_code_3BA, ACT_1BA, c_rock, prefix, line);
        GetFlwSendLine(p, data, size, cur_row_3B, cur_act_3B,
                cur_code_3BH, ACT_1BH, c_rock, prefix, line);
    }
    if(cur_row_4F)
    {
        GetFlwSendLine(p, data, size, cur_row_4F, cur_act_4F,
                cur_code_4FA, ACT_2FA, c_rock, prefix, line);
        GetFlwSendLine(p, data, size, cur_row_4F, cur_act_4F,
                cur_code_4FH, ACT_2FH, c_rock, prefix, line);
    }
    if(cur_row_4B)
    {
        GetFlwSendLine(p, data, size, cur_row_4B, cur_act_4B,
                cur_code_4BA, ACT_2BA, c_rock, prefix, line);
        GetFlwSendLine(p, data, size, cur_row_4B, cur_act_4B,
                cur_code_4BH, ACT_2BH, c_rock, prefix, line);
    }
}
//////////////////////////////////////////////////////////////////////////////
// Func: GetNextLineEnd
// Para: [in] cur_line -- the current line of machine
//       [in] dir      -- the direction of machine
//       [in] mrow     -- start from 0
// Retu: int -- end of next line (left or right decided by dir)
// Desc: get the end for locating the xzq about third line
// Auth: wzwz
// Time: 2012.03.25
/////////////////////////////////////////////////////////////////////////////
static int GetNextLineEnd(MH_KNIT *p, KNIT_PAGE *conline, char dir, int prefix, ushort mrow)
{
    //1st front
    int row_1F = conline->flw_1F;
    int code_1FA = conline->code_1FA;
    int code_1FH = conline->code_1FH;
    char act_1FA = conline->act_1FA;
    char act_1FH = conline->act_1FH;
    //1st back
    int row_1B = conline->flw_1B;
    int code_1BA = conline->code_1BA;
    int code_1BH = conline->code_1BH;
    char act_1BA = conline->act_1BA;
    char act_1BH = conline->act_1BH;
    char act_1F = act_1FA ? act_1FA : act_1FH;
    char act_1B = act_1BA ? act_1BA : act_1BH;
    uchar data[1600] = {0};
    int cc = conline->rock.needle;
    if(conline->rock.drt == ROCK_LEFT)
    {
        cc = -cc;
    }
    enum
    {
        ACT_1FA = 0,
        ACT_1FH = 1,
        ACT_1BA = 2,
        ACT_1BH = 3,
        ACT_2FA = 4,
        ACT_2FH = 5,
        ACT_2BA = 6,
        ACT_2BH = 7
    };
    if(row_1F)
    {
        GetFlwSendLine(p, data, sizeof(data), row_1F, act_1F, code_1FA, ACT_1FA, cc, prefix, mrow);
        GetFlwSendLine(p, data, sizeof(data), row_1F, act_1F, code_1FH, ACT_1FH, cc, prefix, mrow);
    }
    if(row_1B)
    {
        GetFlwSendLine(p, data, sizeof(data), row_1B, act_1B, code_1BA, ACT_1BA, cc, prefix, mrow);
        GetFlwSendLine(p, data, sizeof(data), row_1B, act_1B, code_1BH, ACT_1BH, cc, prefix, mrow);
    }
    if(p->sys_info.cam == 2)
    {
        //2nd front
        int row_2F = conline->flw_2F;
        int code_2FA = conline->code_2FA;
        int code_2FH = conline->code_2FH;
        char act_2FA = conline->act_2FA;
        char act_2FH = conline->act_2FH;
        //2nd back
        int row_2B = conline->flw_2B;
        int code_2BA = conline->code_2BA;
        int code_2BH = conline->code_2BH;
        char act_2BA = conline->act_2BA;
        char act_2BH = conline->act_2BH;
        char act_2F = act_2FA ? act_2FA : act_2FH;
        char act_2B = act_2BA ? act_2BA : act_2BH;
        if(row_2F)
        {
            GetFlwSendLine(p, data, sizeof(data), row_2F, act_2F, code_2FA, ACT_2FA, cc, prefix, mrow);
            GetFlwSendLine(p, data, sizeof(data), row_2F, act_2F, code_2FH, ACT_2FH, cc, prefix, mrow);
        }
        if(row_2B)
        {
            GetFlwSendLine(p, data, sizeof(data), row_2B, act_2B, code_2BA, ACT_2BA, cc, prefix, mrow);
            GetFlwSendLine(p, data, sizeof(data), row_2B, act_2B, code_2BH, ACT_2BH, cc, prefix, mrow);
        }
    }
    /**< 压缩行 */
    uchar *pdir = (uchar*) &conline->rock2_dir;
    uchar *pnum = (uchar*) &conline->rock2_num;
    if(*pdir || *pnum)
    {
        CompressFlw(p, mrow, data, sizeof(data), conline, prefix);
    }
    int width = GetFlowerWidth(p);
    if(prefix)
    {
        width = p->pk_data.pat_width;
    }
    int ext_width = width;
    if(p->ext_piece_num)
    {
        int inter = p->ext_piece_inter;
        int i = 0;
        int start = width + inter;
        for(i = 0; i < 8; i++)
        {
            if(p->ext_piece_enable[i + 1])
            {
                memcpy(&data[start], data, width);
                ext_width = start + width;
            }
            start += width + inter;
        }
        if(!p->ext_piece_enable[0])
        {
            memset(data, 0, width);
        }
    }
    if(!prefix)
    {
        ext_width += MoveStartPoint(p, data);
    }
    return GetRetLen(data, ext_width, 0, !dir);
}
/*
 *
 */
static void GetKnitRockData(MH_KNIT *p, uchar *curt_p, KNIT_PAGE *pcon)
{
    int transfer = HasTransfer(pcon);
    int rock = GetRockPulse(p, pcon->rock.drt, pcon->rock.needle, transfer, pcon->rock.flag);
    curt_p[12] = rock & 0xFF;
    curt_p[13] = (rock >> 8) & 0xFF;
    /*摇床移动的距离对应机头的脉冲数*/
    float mac_type = 12.0;
    if(p->inch_type > 0.4)
    {
        mac_type = p->inch_type;
    }
    int n = p->total_needle * 2540 / mac_type - p->mac_header_inter * 100;
    float fmac = 0.0;
    if(n)
    {
        fmac = (p->belt_right_com - p->belt_left_com) / (float)n;
    }
    float frock = GetRockPulsePerSilk(p);
    if(frock > 0.1 && fmac > 0.1)
    {
        n = rock * fmac / frock;
        curt_p[22] = n & 0xFF;
        curt_p[23] = (n >> 8) & 0x00FF;
    }
    //printf("rock1: %d, %d, %d, %f, %f\n", rock, transfer, n, fmac, frock);
    rock = GetRockShake(p, pcon->rock.shake);
    curt_p[19] = rock & 0xFF;
    curt_p[20] = (rock >> 8) & 0xFF;
    //压缩
    uchar *pdir = (uchar*)&pcon->rock2_dir;
    uchar *pnum = (uchar*)&pcon->rock2_num;
    if(*pdir == 0 && *pnum == 0)
    {
        return;
    }
    rock = GetRockPulse(p, pcon->rock2_dir.drt, pcon->rock2_num.needle, TRUE, pcon->rock2_dir.flag);
    curt_p[16] = rock & 0xFF;
    curt_p[25] = (rock >> 8) & 0xFF;
    if(frock > 0.1 && fmac > 0.1)
    {
        n = rock * fmac / frock;
        curt_p[26] = n & 0xFF;
        curt_p[27] = (n >> 8) & 0x00FF;
    }
    //printf("rock2: %d, %d, %d, %f, %f\n", rock, transfer, n, fmac, frock);
}
static short GetDumuSprt(MH_KNIT *p, uchar speed)
{
    /* 机头实际速度(m/s) */
    float real_speed = 0.03 + 0.014 * (speed - 1);
    /* 机头在度目动作的时间行走的距离,度目电机动作的时间按280us一步，500步计算 */
    float distance = real_speed * 0.14;
    return (int) (distance * 1000 / MM_PER_INCH * p->inch_type);
}
/*
 *
 */
void GetKnitBeforeParam(MH_KNIT *p, uchar *curt_p, uchar mac_dir)
{
    SEND_LINE *psend = (SEND_LINE*)(curt_p - 8);
    enum
    {
        UP = 0, DOWN = 1
    };
    //yarn before down
    int n = p->yarn_before_com[!mac_dir][DOWN][(curt_p[82] - 1) / 5];
    n += p->yarn_before;
    curt_p[104] = n & 0xFF;
    curt_p[105] = (n >> 8) & 0xFF;
    //yarn before up
    n = p->yarn_before_com[!mac_dir][UP][(curt_p[82] - 1) / 5];
    curt_p[106] = n & 0xFF;
    curt_p[107] = (n >> 8) & 0xFF;
    //low speed yarn before down
    curt_p[108] = __max(1, p->mac_low_speed);
    n = p->yarn_before_com[!mac_dir][DOWN][(curt_p[108] - 1) / 5];
    n += p->yarn_before;
    curt_p[109] = n & 0xFF;
    curt_p[110] = (n >> 8) & 0xFF;
    //low speed yarn before up
    n = p->yarn_before_com[!mac_dir][UP][(curt_p[108] - 1) / 5];
    curt_p[111] = n & 0xFF;
    curt_p[112] = (n >> 8) & 0xFF;
    psend->dumu_slow_in_com = p->dumu_before_com[0][(curt_p[108] - 1) / 5];
    psend->dumu_slow_out_com = p->dumu_before_com[1][(curt_p[108] - 1) / 5];
    psend->dumu_high_in_com = p->dumu_before_com[0][(curt_p[82] - 1) / 5];
    psend->dumu_high_out_com = p->dumu_before_com[1][(curt_p[82] - 1) / 5];
    psend->dumu_stop_in_com = p->dumu_before_com[0][0];
    psend->dumu_stop_out_com = p->dumu_before_com[1][0];
    psend->mac_before = p->mac_before_com[!mac_dir][(curt_p[82] - 1) / 5];
    psend->mac_before += GetDumuSprt(p, curt_p[82]);
    psend->mac_low_before = p->mac_before_com[!mac_dir][(curt_p[108] - 1) / 5];
    psend->mac_before += GetDumuSprt(p, curt_p[108]);
#if 0
    printf("before: %d, %d, %d, %d\n", psend->yarn_before_down, psend->yarn_before_up,
            psend->low_yarn_before_down, psend->low_yarn_before_up);
#endif
}
/*
 *
 */
//buf[24]:bit0-系统1前床，只有A位动作，该位置1
//        bit1-系统2前床
//        bit2-系统1后床
//        bit3-系统2后床
static void SetSelectRepeatFlag(PSEND_LINE psend, char cmd1F, char cmd1B, char cmd2F, char cmd2B)
{
    if (IS_ONLY_ACT_A (cmd1F))
    {
        psend->select_repeat.f1 = TRUE;
    }

    if (IS_ONLY_ACT_A (cmd2F))
    {
        psend->select_repeat.f2 = TRUE;
    }

    if (IS_ONLY_ACT_A (cmd1B))
    {
        psend->select_repeat.b1 = TRUE;
    }

    if (IS_ONLY_ACT_A (cmd2B))
    {
        psend->select_repeat.b2 = TRUE;
    }
}
/*
 *
 */
int SwitchLockCam(KNIT_PAGE *pcon, uchar lock, int l0r1)
{
    int ret = 0;
    if(lock != 1 && lock != 2)
    {
        printf("error cam lock\n");
        return -1;
    }
    char cur_act_1FA = pcon->act_1FA;
    char cur_act_1FH = pcon->act_1FH;
    char cur_act_1BA = pcon->act_1BA;
    char cur_act_1BH = pcon->act_1BH;
    char cur_act_2FA = pcon->act_2FA;
    char cur_act_2FH = pcon->act_2FH;
    char cur_act_2BA = pcon->act_2BA;
    char cur_act_2BH = pcon->act_2BH;
    int act_1 = cur_act_1FA || cur_act_1FH || cur_act_1BA || cur_act_1BH;
    int act_2 = cur_act_2FA || cur_act_2FH || cur_act_2BA || cur_act_2BH;
    uchar *psrc;
    uchar *pdes;
    if(lock == 1)//used left cam
    {
        if(l0r1)
        {
            if(act_1 && !act_2)
            {
                //copy cam1 to cam2
                psrc = (uchar*)pcon;
                pdes = psrc + 20;
                memcpy(pdes, psrc, 20);
                pcon->gauze2_9 = pcon->gauze1_9;
                pcon->gauze2_1 = pcon->gauze1_1;
                pcon->gout2 = pcon->gout1;
                pcon->dumu2 = pcon->dumu1;
                memset(psrc, 0, 20);
                pcon->gauze1_9 = 0;
                pcon->gauze1_1 = 0;
                pcon->gout1 = 0;
                pcon->dumu1 = 0;
                ret = 1;
            }
        }
        else
        {
            if(!act_1 && act_2)
            {
                //copy cam2 to cam1
                pdes = (uchar*)pcon;
                psrc = pdes + 20;
                memcpy(pdes, psrc, 20);
                pcon->gauze1_9 = pcon->gauze2_9;
                pcon->gauze1_1 = pcon->gauze2_1;
                pcon->gout1 = pcon->gout2;
                pcon->dumu1 = pcon->dumu2;
                memset(pdes, 0, 20);
                pcon->gauze2_9 = 0;
                pcon->gauze2_1 = 0;
                pcon->gout2 = 0;
                pcon->dumu2 = 0;
                ret = 1;
            }
        }
    }
    else//used right cam
    {
        if(l0r1)
        {
            if(!act_1 && act_2)
            {
                //copy cam2 to cam1
                pdes = (uchar*) pcon;
                psrc = pdes + 20;
                memcpy(pdes, psrc, 20);
                pcon->gauze1_9 = pcon->gauze2_9;
                pcon->gauze1_1 = pcon->gauze2_1;
                pcon->gout1 = pcon->gout2;
                pcon->dumu1 = pcon->dumu2;
                memset(pdes, 0, 20);
                pcon->gauze2_9 = 0;
                pcon->gauze2_1 = 0;
                pcon->gout2 = 0;
                pcon->dumu2 = 0;
                ret = 2;
            }
        }
        else
        {
            if(act_1 && !act_2)
            {
                //copy cam1 to cam2
                psrc = (uchar*) pcon;
                pdes = psrc + 20;
                memcpy(pdes, psrc, 20);
                pcon->gauze2_9 = pcon->gauze1_9;
                pcon->gauze2_1 = pcon->gauze1_1;
                pcon->gout2 = pcon->gout1;
                pcon->dumu2 = pcon->dumu1;
                memset(psrc, 0, 20);
                pcon->gauze1_9 = 0;
                pcon->gauze1_1 = 0;
                pcon->gout1 = 0;
                pcon->dumu1 = 0;
                ret = 2;
            }
        }
    }
    if(ret)
    {
        printf("lock cam L1R2: %d\n", ret);
    }
    return ret;
}
/*
 * get next knit data for dsp
 * param line: start from 1
 */
void GetNormalKnitData(MH_KNIT *p, uchar *data, ushort line, int prefix, int aux_index)
{
    //clear data
    int size = SEND_MAX_SIZE;
    memset(data, 0, size);
    SEND_LINE *psend = (SEND_LINE*)data;
    KNIT_PAGE curt_conline;
    //printf("%d, %d\n", line, prefix);
    if(prefix)
    {
        pk_get_cnt_buf(p, &curt_conline, line);
    }
    else if(aux_index > -1)
    {
        GetAuxConPage(p, &curt_conline, aux_index, line);
    }
    else
    {
        KNIT_PAGE *pcon = GetControlPage(p, line);
        if(pcon)
        {
            memcpy(&curt_conline, pcon, sizeof(KNIT_PAGE));
            //cam lock
            if(p->ctrl_page && line > 0 && line <= p->total_line && p->cam_lock && p->sys_info.cam > 1)
            {
                if(p->ctrl_page[line - 1].threhold <= 0)
                {
                    SwitchLockCam(&curt_conline, p->cam_lock, line & 1);
                }
            }
        }
    }
    --line;
    uchar *curt_p = &data[8];
    //direction 1=L 0=R
    enum {RIGHT = 0, LEFT = 1};
    char mac_dir = line & 1;
    //1st-front
    int cur_row_1F = curt_conline.flw_1F;
    char cur_act_1FA = curt_conline.act_1FA;
    int cur_code_1FA = curt_conline.code_1FA;
    char cur_act_1FH = curt_conline.act_1FH;
    int cur_code_1FH = curt_conline.code_1FH;
    //1st-back
    int cur_row_1B = curt_conline.flw_1B;
    char cur_act_1BA = curt_conline.act_1BA;
    int cur_code_1BA = curt_conline.code_1BA;
    char cur_act_1BH = curt_conline.act_1BH;
    int cur_code_1BH = curt_conline.code_1BH;

    char cur_act_1F = cur_act_1FA ? cur_act_1FA : cur_act_1FH;
    char cur_act_1B = cur_act_1BA ? cur_act_1BA : cur_act_1BH;

    int has_knit = FALSE;
    if(IsActKnit(cur_act_1F))
    {
        has_knit = TRUE;
    }
    if(IsActKnit(cur_act_1B))
    {
        has_knit = TRUE;
    }
    //2nd-front
    int cur_row_2F = curt_conline.flw_2F;
    char cur_act_2FA = curt_conline.act_2FA;
    int cur_code_2FA = curt_conline.code_2FA;
    char cur_act_2FH = curt_conline.act_2FH;
    int cur_code_2FH = curt_conline.code_2FH;
    //2nd-back
    int cur_row_2B = curt_conline.flw_2B;
    char cur_act_2BA = curt_conline.act_2BA;
    int cur_code_2BA = curt_conline.code_2BA;
    char cur_act_2BH = curt_conline.act_2BH;
    int cur_code_2BH = curt_conline.code_2BH;

    char cur_act_2F = cur_act_2FA ? cur_act_2FA : cur_act_2FH;
    char cur_act_2B = cur_act_2BA ? cur_act_2BA : cur_act_2BH;
    if(p->sys_info.cam == 2)
    {
        if(IsActKnit(cur_act_2F))
        {
            has_knit = 1;
        }
        if(IsActKnit(cur_act_2B))
        {
            has_knit = 1;
        }
    }

    SetSelectRepeatFlag(psend, cur_act_1F, cur_act_1B, cur_act_2F, cur_act_2B);

    //rock needle
    int cc = curt_conline.rock.needle;
    if(curt_conline.rock.drt == ROCK_LEFT)
    {
        cc = -cc;
    }
    //curt_p[16] = cc;
    //flower data
    enum
    {
        ACT_1FA = 0,
        ACT_1FH = 1,
        ACT_1BA = 2,
        ACT_1BH = 3,
        ACT_2FA = 4,
        ACT_2FH = 5,
        ACT_2BA = 6,
        ACT_2BH = 7
    };
    if(cur_row_1F)
    {
        GetFlwSendLine(p, &data[288], size, cur_row_1F, cur_act_1F, cur_code_1FA, ACT_1FA, cc, prefix, line);
        GetFlwSendLine(p, &data[288], size, cur_row_1F, cur_act_1F, cur_code_1FH, ACT_1FH, cc, prefix, line);
    }
    if(cur_row_1B)
    {
        GetFlwSendLine(p, &data[288], size, cur_row_1B, cur_act_1B, cur_code_1BA, ACT_1BA, cc, prefix, line);
        GetFlwSendLine(p, &data[288], size, cur_row_1B, cur_act_1B, cur_code_1BH, ACT_1BH, cc, prefix, line);
    }
    if(cur_row_2F)
    {
        GetFlwSendLine(p, &data[288], size, cur_row_2F, cur_act_2F, cur_code_2FA, ACT_2FA, cc, prefix, line);
        GetFlwSendLine(p, &data[288], size, cur_row_2F, cur_act_2F, cur_code_2FH, ACT_2FH, cc, prefix, line);
    }
    if(cur_row_2B)
    {
        GetFlwSendLine(p, &data[288], size, cur_row_2B, cur_act_2B, cur_code_2BA, ACT_2BA, cc, prefix, line);
        GetFlwSendLine(p, &data[288], size, cur_row_2B, cur_act_2B, cur_code_2BH, ACT_2BH, cc, prefix, line);
    }
    /**< 压缩行 */
    uchar *pdir = (uchar*)&curt_conline.rock2_dir;
    uchar *pnum = (uchar*)&curt_conline.rock2_num;
    if(*pdir || *pnum)
    {
        CompressFlw(p, line, &data[288], size - 288, &curt_conline, prefix);
    }
//1
    int width = GetFlowerWidth(p);
    if(prefix)
    {
        width = p->pk_data.pat_width;
    }
    //con data
    curt_p[0] = GetSanjiaoState(p, cur_act_1F, mac_dir);//1F
    curt_p[1] = GetSanjiaoState(p, cur_act_1B, mac_dir);//1B
    curt_p[2] = GetSanjiaoState(p, cur_act_2F, mac_dir);//2F
    curt_p[3] = GetSanjiaoState(p, cur_act_2B, mac_dir);//2B
    if(p->sys_info.cam == 1)
    {
        /* 第二次摇床对应三角 */
        curt_p[4] = GetSanjiaoState(p, curt_conline.act_3FA, mac_dir);
        curt_p[5] = GetSanjiaoState(p, curt_conline.act_3BA, mac_dir);
    }
    else
    {
        curt_p[4] = GetSanjiaoState(p, curt_conline.act_3FA, mac_dir);
        curt_p[5] = GetSanjiaoState(p, curt_conline.act_3BA, mac_dir);
        curt_p[6] = GetSanjiaoState(p, curt_conline.act_4FA, mac_dir);
        curt_p[7] = GetSanjiaoState(p, curt_conline.act_4BA, mac_dir);
    }
    //qdb
    if(p->board_enable)
    {
        //jiazi bi
        curt_p[17] |= GetClipOff(p, curt_conline.clip_off);
        curt_p[17] |= GetClipOn(p, curt_conline.clip_on);
        curt_p[ARM2DSP_SPEC_BYTE] |= curt_conline.scissor;
        if(curt_conline.board)//qdb raise
        {
            curt_p[ARM2DSP_SPEC_BYTE] |= ARM2DSP_QDB_RAISE;
        }
    }
    psend->pause = curt_conline.pause;
    curt_p[ARM2DSP_SPEC_BYTE] |= p->sys_info.lock ? ARM2DSP_LOCK_MAC : 0;
    //总件数完成
    curt_p[ARM2DSP_SPEC_BYTE] |= p->done_cloth >= p->total_cloth ? ARM2DSP_FORBID_RUN : 0;
    //双机头工作方式
    curt_p[ARM2DSP_SSHA_BYTE - 8] |= (p->header_type.right_forbid << 1) | (p->header_type.left_forbid);
    GetDumuData(p, curt_p, mac_dir,
            cur_act_1F, cur_act_2F, cur_act_1B, cur_act_2B,
            curt_conline.dumu1, curt_conline.dumu2, 1);
    //sink data
    GetSinkData(p, curt_p, mac_dir, cur_act_1F, cur_act_2F, cur_act_1B, cur_act_2B,
            curt_conline.act_3FA, curt_conline.act_4FA, curt_conline.act_3BA, curt_conline.act_4BA,
            curt_conline.sink);
    //yarn in/out
    if(p->board_enable)
    {
        curt_p[0] |= curt_conline.gout1 & 0x03;
        curt_p[2] |= curt_conline.gout2 & 0x03;
    }
    psend->board_pull = p->board_param.pull;
    //sudu
    if(p->run_knot)
    {
        curt_p[82] = p->mac_low_speed;
    }
    else
    {
        uchar speed_sect = curt_conline.speed;
        if(p->board_enable && ((curt_conline.gout1 & 1) || (curt_conline.gout2 & 1)))//yarn in
        {
            speed_sect = SPEED_SECT_FOR_BOARD;
        }
        switch(p->gui_speed_type)
        {
        case SPEED_HIGH:
            {
                if(!cur_act_1F && !cur_act_1B && !cur_act_2F && !cur_act_2B && p->mac_empty_speed)
                {
                    curt_p[82] = p->mac_empty_speed;
                }
                else
                {
                    curt_p[82] = GetMacRunSpeed(p, speed_sect - 1);
                }
            }
            break;
        case SPEED_LIMIT:
            {
                /*if(!cur_act_1F && !cur_act_1B && !cur_act_2F && !cur_act_2B && p->mac_empty_speed)
                {
                    curt_p[82] = p->mac_empty_speed;
                }
                else*/
                {
                    curt_p[82] = __min(GetMacRunSpeed(p, speed_sect - 1), p->mac_mid_speed);
                }
            }
            break;
        case SPEED_LOW:
            curt_p[82] = p->mac_low_speed;
            break;
        case SPEED_INCH:
            {
                curt_p[121] = p->inch_pulse;
                curt_p[122] = p->inch_pulse >> 8;
                curt_p[118] |= ARM2DSP_INCHRUN_BIT;
            }
            break;
        default:
            break;
        }
    }
    //max speed
    uchar max_speed = p->mac_high_speed;
    curt_p[82] = __min(curt_p[82], max_speed);
    curt_p[82] = __max(1, curt_p[82]);
    //low roller
    curt_p[83] = GetRollRunSpeed(p, curt_conline.low_roll - 1);
    //kaihe
    curt_p[85] = GetSwitchRunSpeed(p, curt_conline.kaihe - 1);
    //end point
    int tmp1 = GetYarnEndPoint(&data[288], 1, width, cur_act_1F, 0, mac_dir);
    int tmp2 = GetYarnEndPoint(&data[288], 1, width, cur_act_1B, 1, mac_dir);
    //printf("%d: %d, %d\n", line + 1, tmp1, tmp2);
    int cur_end_1st = 0;
    if(mac_dir)//left
    {
        if(tmp1)
        {
            if(tmp2)
            {
                cur_end_1st = __min(tmp1, tmp2);
            }
            else
            {
                cur_end_1st = tmp1;
            }
        }
        else
        {
            cur_end_1st = tmp2;
        }
    }
    else//right
    {
        cur_end_1st = __max(tmp1, tmp2);
    }
    if(cur_row_1F)
    {
        tmp1 = GetYarnCodeEnd(p, cur_row_1F, mac_dir);
        if(tmp1)
        {
            if(cur_end_1st)
            {
                cur_end_1st = mac_dir ? __min(cur_end_1st, tmp1) : __max(cur_end_1st, tmp1);
            }
            else
            {
                cur_end_1st = tmp1;
            }
        }
        //DEBUG_OUT("%d: %d, %d, %d\n", line + 1, cur_row_1F, mac_dir, tmp1);
    }
    if(cur_row_1B != cur_row_1F && cur_row_1B)
    {
        tmp1 = GetYarnCodeEnd(p, cur_row_1B, mac_dir);
        if(tmp1)
        {
            if(cur_end_1st)
            {
                cur_end_1st = mac_dir ? __min(cur_end_1st, tmp1) : __max(cur_end_1st, tmp1);
            }
            else
            {
                cur_end_1st = tmp1;
            }
        }
    }
    int cur_end_2nd = 0;
    if(p->sys_info.cam == 2)
    {
        tmp1 = GetYarnEndPoint(&data[288], 1, width, cur_act_2F, 2, mac_dir);
        tmp2 = GetYarnEndPoint(&data[288], 1, width, cur_act_2B, 3, mac_dir);
        //DEBUG_OUT("%d, %d, %d\n", __LINE__, tmp1, tmp2);
        if(mac_dir)//left
        {
            if(tmp1)
            {
                if(tmp2)
                {
                    cur_end_2nd = __min(tmp1, tmp2);
                }
                else
                {
                    cur_end_2nd = tmp1;
                }
            }
            else
            {
                cur_end_2nd = tmp2;
            }
        }
        else//right
        {
            cur_end_2nd = __max(tmp1, tmp2);
        }
        if(cur_row_2F)
        {
            tmp1 = GetYarnCodeEnd(p, cur_row_2F, mac_dir);
            if(tmp1)
            {
                if(cur_end_2nd)
                {
                    cur_end_2nd = mac_dir ? __min(cur_end_2nd, tmp1) : __max(cur_end_2nd, tmp1);
                }
                else
                {
                    cur_end_2nd = tmp1;
                }
            }
        }
        if(cur_row_2B != cur_row_2F && cur_row_2B)
        {
            tmp1 = GetYarnCodeEnd(p, cur_row_2B, mac_dir);
            if(tmp1)
            {
                if(cur_end_2nd)
                {
                    cur_end_2nd = mac_dir ? __min(cur_end_2nd, tmp1) : __max(cur_end_2nd, tmp1);
                }
                else
                {
                    cur_end_2nd = tmp1;
                }
            }
        }
    }
//2
    //yarn stop
    int yinta = curt_conline.yinta;
    char yarn_chng[2][GAUZE_NUM] = {{0}};
    memcpy(yarn_chng, p->gauze_exchange, sizeof(yarn_chng));

    curt_p[8] = curt_conline.gauze1_1;
    curt_p[9] = curt_conline.gauze2_1;
    curt_p[ARM2DSP_GAUZE_SYS1_EXTRA] = curt_conline.gauze1_9;
    curt_p[ARM2DSP_GAUZE_SYS2_EXTRA] = curt_conline.gauze2_9;

    int yarn_used[GAUZE_NUM] = {0};
    int yarn_stop = 0;
    int cur_yarn[GAUZE_NUM] = {0};
    if(1)
    {
        int gauze_1 = (curt_p[8] << 8) | curt_p[ARM2DSP_GAUZE_SYS1_EXTRA];
        int gauze_2 = (curt_p[9] << 8) | curt_p[ARM2DSP_GAUZE_SYS2_EXTRA];
        int i = 0;
        for(i = 0; i < p->sys_info.gauze; i++)
        {
            if((gauze_1 & (0x8000 >> i)) || (gauze_2 & (0x8000 >> i)))
            {
                if(yinta & 0x80)
                {
                    ushort flw_line = gauze_1 & (0x8000 >> i) ? cur_row_1F : cur_row_2F;
                    uchar system = gauze_1 & (0x8000 >> i) ? 1 : 2;;
                    if(curt_conline.end.dj)
                    {
                        yarn_stop = GetYintaPosSeiki(&curt_conline, flw_line, system, i + 1, mac_dir);
                    }
                    else
                    {
                        yarn_stop = GetYintaPos(p, &curt_conline, flw_line, system, i + 1, mac_dir);
                    }
                    //DEBUG_OUT("%d: %d-%d\n", line + 1, i + 1, yarn_stop);
                }
                else
                {
                    yarn_stop = (gauze_1 & (0x8000 >> i) ? cur_end_1st : cur_end_2nd);
                    //DEBUG_OUT("%d-%d-%d-%d\n", i + 1, yarn_stop, cur_end_1st, cur_end_2nd);
                }
                //DEBUG_OUT("%d: %d-%d\n", line + 1, i + 1, yarn_stop);
                cur_yarn[i] = yarn_stop;
                //yarn_used[i] = gauze_1 & (0x8000 >> i) ? 1 : 2;
            }
        }
    }
    //宽纱嘴
    int gauze_1 = (curt_p[8] << 8) | curt_p[ARM2DSP_GAUZE_SYS1_EXTRA];
    int gauze_2 = (curt_p[9] << 8) | curt_p[ARM2DSP_GAUZE_SYS2_EXTRA];
    int i = 0;
    //change yarn
    int curt_yarn_src[GAUZE_NUM] = {0};
    memcpy(curt_yarn_src, cur_yarn, sizeof(cur_yarn));
    memset(cur_yarn, 0, sizeof(cur_yarn));
    int gauze_1_src = gauze_1;
    int gauze_2_src = gauze_2;
    gauze_1 = 0;
    gauze_2 = 0;
    for(i = 0; i < p->sys_info.gauze; i++)
    {
        if(gauze_1_src & (0x8000 >> i))
        {
            if(yarn_chng[0][i] && yarn_chng[0][i] != i + 1)
            {
                gauze_1 |= 0x8000 >> (yarn_chng[0][i] - 1);
                cur_yarn[yarn_chng[0][i] - 1] = curt_yarn_src[i];
                yarn_used[yarn_chng[0][i] - 1] = 1;
            }
            else
            {
                gauze_1 |= 0x8000 >> i;
                cur_yarn[i] = curt_yarn_src[i];
                yarn_used[i] = 1;
            }
            if(yarn_chng[1][i])
            {
                gauze_1 |= 0x8000 >> (yarn_chng[1][i] - 1);
                cur_yarn[yarn_chng[1][i] - 1] = curt_yarn_src[i];
                yarn_used[yarn_chng[1][i] - 1] = 1;
            }
        }
        if(gauze_2_src & (0x8000 >> i))
        {
            if(yarn_chng[0][i] && yarn_chng[0][i] != i + 1)
            {
                gauze_2 |= 0x8000 >> (yarn_chng[0][i] - 1);
                cur_yarn[yarn_chng[0][i] - 1] = curt_yarn_src[i];
                yarn_used[yarn_chng[0][i] - 1] = 2;
            }
            else
            {
                gauze_2 |= 0x8000 >> i;
                cur_yarn[i] = curt_yarn_src[i];
                yarn_used[i] = 2;
            }
            if(yarn_chng[1][i])
            {
                gauze_2 |= 0x8000 >> (yarn_chng[1][i] - 1);
                cur_yarn[yarn_chng[1][i] - 1] = curt_yarn_src[i];
                yarn_used[yarn_chng[1][i] - 1] = 2;
            }
        }
    }
    gauze_1_src = gauze_1;
    gauze_2_src = gauze_2;
    //extent yarn
    if(p->ext_piece_num)
    {
        int inter = p->ext_piece_inter;
        int i = 0, j = 0;
        int start = width + 288 + inter;
        for(i = 0; i < 8; i++)
        {
            if(p->ext_piece_enable[i + 1])
            {
                memcpy(&data[start], &data[288], width);
                /*printf("start: %d, %d, %d, %d\n", start, width, inter, i);
                for(j = 0; j < width; ++j)
                {
                    printf("%02X ", data[start + j]);
                }*/
                char yarn[GAUZE_NUM] = {0};
                for(j = 0; j < GAUZE_NUM; ++j)
                {
                    uchar g = p->ext_piece_yarn[i + 1][j];
                    if(g >= 11 && g <= 18)
                    {
                        g -= 2;
                    }
                    yarn[j] = g;
                }
                //memcpy(yarn, p->ext_piece_yarn[i + 1], sizeof(yarn));
                for(j = 0; j < p->sys_info.gauze; j++)
                {
                    //0x80表示是续片纱嘴
                    if(yarn_used[j] && !(yarn_used[j] & 0x80) && yarn[j] > 0 && yarn[j] < GAUZE_NUM + 1)
                    {
                        cur_yarn[yarn[j] - 1] = cur_yarn[j] + (width + inter) * (i + 1);
                        yarn_used[yarn[j] - 1] = yarn_used[j] | 0x80;
                        if(yarn_used[j] == 1)
                        {
                            gauze_1 |= 0x8000 >> (yarn[j] - 1);
                        }
                        else
                        {
                            gauze_2 |= 0x8000 >> (yarn[j] - 1);
                        }
                    }
                }
            }
            start += width + inter;
        }
        //去掉原片
        if(!p->ext_piece_enable[0])
        {
            memset(&data[288], 0, width);
            for(i = 0; i < p->sys_info.gauze; i++)
            {
                if((gauze_1 & (0x8000 >> i)) && (gauze_1_src & (0x8000 >> i)))
                {
                    gauze_1 &= ~(0x8000 >> i);
                    yarn_used[i] = 0;
                }
                if((gauze_2 & (0x8000 >> i)) && (gauze_2_src & (0x8000 >> i)))
                {
                    gauze_2 &= ~(0x8000 >> i);
                    yarn_used[i] = 0;
                }
            }
        }
    }
//3
    curt_p[8] = gauze_1 >> 8;
    curt_p[9] = gauze_2 >> 8;
    curt_p[ARM2DSP_GAUZE_SYS1_EXTRA] = gauze_1;
    curt_p[ARM2DSP_GAUZE_SYS2_EXTRA] = gauze_2;
    //DEBUG_OUT("right_jt_yarn: %d\n", right_jt_yarn);
    //最后2行落布主拉布不工作
    if(line + 1 == p->total_line || line + 2 == p->total_line)
    {
        if(!gauze_1 && !gauze_2 && has_knit)
        {
            curt_p[83] = 0;
        }
    }
    //起针点
    if(!prefix || p->knit_state.drop_cloth)
    {
        int n = MoveStartPoint(p, &data[288]);
        int i = 0;
        /*for(i = 0; i < 8; ++i)
        {
            printf("%d, %d\n", data[288 + i], data[288 + 623 - i]);
        }*/
        for(i = 0; i < p->sys_info.gauze; i++)
        {
            cur_yarn[i] = yarn_used[i] & 0x7F ? cur_yarn[i] + n : 0;
        }
    }
    //1st yarn out
    if((curt_conline.gout1 & 2) && p->board_enable)
    {
        int i = 0;
        for(i = 0; i < p->sys_info.gauze; i++)
        {
            if((yarn_used[i] & 0x7F) == 1)
            {
                if(mac_dir)
                {
                    cur_yarn[i] = -GetYarnLeftOutStop(p) - p->yarn_out.stop[0][i];
                }
                else
                {
                    cur_yarn[i] = p->total_needle + GetYarnRightOutStop(p) + p->yarn_out.stop[1][i];
                }
            }
        }
    }
    else
    {
        for(i = 0; i < p->sys_info.gauze; i++)
        {
            if(gauze_1 & (0x8000 >> i))
            {
                if(mac_dir)//left
                {
                    cur_yarn[i] -= GetRunYarnStop(p, 0, curt_conline.stop - 1, i);
                }
                else
                {
                    cur_yarn[i] += GetRunYarnStop(p, 1, curt_conline.stop - 1, i);
                }
            }
        }
    }
#if 1
//5
    //2nd yarn out
    if((curt_conline.gout2 & 2) && p->board_enable)
    {
        int i = 0;
        for(i = 0; i < p->sys_info.gauze; i++)
        {
            if((yarn_used[i] & 0x7F) == 2)
            {
                if(mac_dir)
                {
                    cur_yarn[i] = -GetYarnLeftOutStop(p) - p->yarn_out.stop[0][i];
                }
                else
                {
                    cur_yarn[i] = p->total_needle + GetYarnRightOutStop(p) + p->yarn_out.stop[1][i];
                }
            }
        }
    }
    else
    {
        for(i = 0; i < p->sys_info.gauze; i++)
        {
            if(gauze_2 & (0x8000 >> i))
            {
                if(mac_dir)//left
                {
                    cur_yarn[i] -= GetRunYarnStop(p, 0, curt_conline.stop - 1, i);
                }
                else
                {
                    cur_yarn[i] += GetRunYarnStop(p, 1, curt_conline.stop - 1, i);
                }
            }
        }
    }
    for(i = 0; i < 8; i++)
    {
        curt_p[86 + (i << 1)] = cur_yarn[i] & 0xFF;
        curt_p[87 + (i << 1)] = (cur_yarn[i] >> 8) & 0xFF;
    }
    for(i = 8; i < p->sys_info.gauze; i++)
    {
        curt_p[ARM2DSP_GAUZE9_STOPL + ((i - 8) << 1)] = cur_yarn[i] & 0xFF;
        curt_p[ARM2DSP_GAUZE9_STOPH + ((i - 8) << 1)] = (cur_yarn[i] >> 8) & 0xFF;
    }
#if 0
    for(i = 0; i < 8; ++i)
    {
        short *pstop = &psend->stop1;
        printf("%d-%d ", i + 1, pstop[i]);
    }
    printf("\n");
#endif
    //
    if(curt_conline.dmbz == FORBID_PROBE)
    {
        psend->forbid.probe = TRUE;
    }
    //rock
    /* 设置摇床脉冲数和针板偏移脉冲数 */
    GetKnitRockData(p, curt_p, &curt_conline);
    /*阀值*/
    RUN_THREHOLD run_threhold = { 0 };
    compress_get_threhold (p, line, &run_threhold);
    int threhold = run_threhold.threhold + p->start_needle - p->left_bound;
    if(run_threhold.threhold > 0)
    {
        curt_p[32] = threhold & 0x00FF;
        curt_p[33] = (threhold & 0xFF00) >> 8;
    }
    int third_line = 0;
    KNIT_PAGE next_conline = {0};
    ushort next_line = GetNextLine(p, line + 1, &prefix, &aux_index);
    if(prefix)
    {
        pk_get_cnt_buf(p, &next_conline, next_line);
    }
    else if(aux_index > -1)
    {
        GetAuxConPage(p, &next_conline, aux_index, next_line);
    }
    else
    {
        KNIT_PAGE *pcon = GetControlPage(p, next_line);
        if(pcon)
        {
            memcpy(&next_conline, pcon, sizeof(KNIT_PAGE));
            //cam lock
            if(p->ctrl_page && next_line > 0 && next_line <= p->total_line && p->cam_lock && p->sys_info.cam > 1)
            {
                if(p->ctrl_page[next_line - 1].threhold <= 0)
                {
                    SwitchLockCam(&curt_conline, p->cam_lock, next_line & 1);
                }
            }
        }
    }
    if(p->board_enable && line + 1 == p->total_line && next_line == 1)//落布标志，让罗拉转
    {
        curt_p[ARM2DSP_SPEC_BYTE] |= ARM2DSP_DROP_CLOTH;
    }
    third_line = GetNextLineEnd(p, &next_conline, mac_dir, prefix, next_line - 1);
    //nextline yarn
    psend->next_gauze1_1 = next_conline.gauze1_1;
    curt_p[10] = next_conline.gauze1_1;
    curt_p[11] = next_conline.gauze2_1;
    curt_p[ARM2DSP_GAUZE_SYS1_EXTRA_NEXT] = next_conline.gauze1_9;
    curt_p[ARM2DSP_GAUZE_SYS2_EXTRA_NEXT] = next_conline.gauze2_9;
    gauze_1_src = (curt_p[10] << 8) | curt_p[ARM2DSP_GAUZE_SYS1_EXTRA_NEXT];
    gauze_2_src = (curt_p[11] << 8) | curt_p[ARM2DSP_GAUZE_SYS2_EXTRA_NEXT];
    //change yarn
    gauze_1 = 0;
    gauze_2 = 0;
    memset(yarn_used, 0, sizeof(yarn_used));
    for(i = 0; i < p->sys_info.gauze; i++)
    {
        if(gauze_1_src & (0x8000 >> i))
        {
            if(yarn_chng[0][i] && yarn_chng[0][i] != i + 1)
            {
                gauze_1 |= 0x8000 >> (yarn_chng[0][i] - 1);
                yarn_used[yarn_chng[0][i] - 1] = 1;
                //DEBUG_OUT("%d, %d\n", i + 1, yarn_chng[0][i]);
            }
            else
            {
                gauze_1 |= 0x8000 >> i;
                yarn_used[i] = 1;
            }
            if(yarn_chng[1][i])
            {
                gauze_1 |= 0x8000 >> (yarn_chng[1][i] - 1);
                yarn_used[yarn_chng[1][i] - 1] = 1;
            }
        }
        if(gauze_2_src & (0x8000 >> i))
        {
            if(yarn_chng[0][i] && yarn_chng[0][i] != i + 1)
            {
                gauze_2 |= 0x8000 >> (yarn_chng[0][i] - 1);
                yarn_used[yarn_chng[0][i] - 1] = 2;
            }
            else
            {
                gauze_2 |= 0x8000 >> i;
                yarn_used[i] = 2;
            }
            if(yarn_chng[1][i])
            {
                gauze_2 |= 0x8000 >> (yarn_chng[1][i] - 1);
                yarn_used[yarn_chng[1][i] - 1] = 2;
            }
        }
    }
//4
    //DEBUG_OUT("%d: %d  \n", yarn_used[0], yarn_used[2]);
    //DEBUG_OUT("1: %04X, %04X\n", gauze_1, gauze_2);
    //extent yarn
    gauze_1_src = gauze_1;
    gauze_2_src = gauze_2;
    if(p->ext_piece_num)
    {
        int i = 0;
        for(i = 0; i < 8; i++)
        {
            if(p->ext_piece_enable[i + 1])
            {
                char yarn[GAUZE_NUM] = {0};
                int j = 0;
                for(j = 0; j < GAUZE_NUM; ++j)
                {
                    uchar g = p->ext_piece_yarn[i + 1][j];
                    if(g >= 11 && g <= 18)
                    {
                        g -= 2;
                    }
                    yarn[j] = g;
                }
                //memcpy(yarn, p->ext_piece_yarn[i + 1], sizeof(yarn));
                for(j = 0; j < p->sys_info.gauze; j++)
                {
                    if(yarn_used[j])
                    {
                        if(yarn_used[j] == 1)
                        {
                            gauze_1 |= 0x8000 >> (yarn[j] - 1);
                        }
                        else
                        {
                            gauze_2 |= 0x8000 >> (yarn[j] - 1);
                        }
                    }
                }
            }
        }
        //DEBUG_OUT("2: %04X, %04X\n", gauze_1, gauze_2);
        //去掉原片
        if(!p->ext_piece_enable[0])
        {
            for(i = 0; i < p->sys_info.gauze; i++)
            {
                if((gauze_1 & (0x8000 >> i)) && (gauze_1_src & (0x8000 >> i)))
                {
                    gauze_1 &= ~(0x8000 >> i);
                }
                if((gauze_2 & (0x8000 >> i)) && (gauze_2_src & (0x8000 >> i)))
                {
                    gauze_2 &= ~(0x8000 >> i);
                }
            }
        }
    }
    curt_p[10] = gauze_1 >> 8;
    curt_p[11] = gauze_2 >> 8;
    curt_p[ARM2DSP_GAUZE_SYS1_EXTRA_NEXT] = gauze_1;
    curt_p[ARM2DSP_GAUZE_SYS2_EXTRA_NEXT] = gauze_2;
    curt_p[14] = third_line & 0xFF;
    curt_p[15] = (third_line >> 8) & 0xFF;
    //ret len
    curt_p[102] = p->mac_ret_len;
    //rock speed
    curt_p[103] = p->rock_speed;

    if(run_threhold.limit_speed > 0)
    {
        if(curt_p[82] > run_threhold.limit_speed)
        {
            curt_p[82] = run_threhold.limit_speed;
        }
    }

    /*提前量设置*/
    GetKnitBeforeParam(p, curt_p, mac_dir);

    /**< 粗目值 */
    short rude = GetRudeDumu(p, curt_conline.high_roll - 1);
    /* 下一行是翻针，取消当前行的紧目 */
    if(HasTransfer(&next_conline))
    {
        if(rude < 0)
        {
            rude = 0;
        }
    }
    psend->rude_dumu = rude;
    //curt_p[151] = n & 0x00FF;
    //curt_p[152] = (n & 0xFF00) >> 8;

    //high roll
    int n = GetRabRunSpeed(p, curt_conline.high_roll - 1);
    if(n & 0x80)//倒转
    {
        psend->high_roll_open = -(0xFFFFFF00 | n);        //倒转的幅度，由下位机转换成步数
        n = 0 - GetHighRollerFrequency(p, 90);
    }
    else
    {
        n = GetHighRollerFrequency(p, n);
    }
    curt_p[113] = n & 0xFF;
    curt_p[114] = (n >> 8) & 0xFF;
    curt_p[115] = (n >> 16) & 0xFF;
    curt_p[116] = (n >> 24) & 0xFF;

    curt_p[117] = p->rab_percent;
    //printf("rab percent: %d\n", p->rab_percent);
    //shongsha
    int songsha_mode = p->yarn_feeder_mode;
    int left_songsha = p->left_feeder_enable;
    int rght_songsha = p->right_feeder_enable;
    uchar songsha_speed = GetFeederRunSpeed(p, curt_conline.speed - 1);
    curt_p[119] = songsha_mode ? (left_songsha ? songsha_speed : 0) : (has_knit && left_songsha ? songsha_speed : 0);
    curt_p[120] = songsha_mode ? (rght_songsha ? songsha_speed : 0) : (has_knit && rght_songsha ? songsha_speed : 0);
    //mac before
    curt_p[125] = p->mac_before_com[!mac_dir][(curt_p[82] - 1) / 5];
    curt_p[126] = p->mac_before_com[!mac_dir][(curt_p[108] - 1) / 5];
    psend->dumu_add_percent = p->dumu_add_percent;
    psend->probe_capacity = p->probe_shield * p->inch_type / MM_PER_INCH;
    psend->rude_capacity = p->second_dumu_com;
    //DEBUG_OUT("end: %d\n", line);
    if(p->sys_info.cam == 2)
    {
        //if(p->sys_info.mac == MAC_FY_3G_DOUBLE)
        {
            curt_p[82] = curt_p[82] * 0.8 + 0.5;
        }
    }
    else
    {
        if(p->sys_info.mac == MAC_DOUBLE_JITOU)
        {
            curt_p[82] = curt_p[82] * 0.5 + 0.5;
        }
    }
#endif
    //printf("stop1: %d, %d\n", psend->stop1, p->left_bound);
}
